 %___初始化种群加入混沌反向学习，加入非线性权重，加入非线性时变权重，加入黄金正弦算法______________________________________________________________________________%
%  Dwarf Mongoose Optimization Algorithm 
%_______________________________________________________________________________________%
function [BEF2,BEP2,BestCost2]=CDMO(nPop,MaxIt,VarMin,VarMax,nVar,fobj)
%%%%%%%%%%%%%%%%%%%%%%%%%%  非线性因子参数  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% wmin=0.;
% wmax=0.25;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% LB=VarMin;
% UB=VarMax;
% Dim=nVar;%
%nVar=5;             % 决策变量的数量

VarSize=[1 nVar];   % 决策变量矩阵大小

%VarMin=-10;         % 决策变量下限
%VarMax= 10;         % 决策变量上限

%% ABC Settings

% MaxIt=1000;% 最大迭代次数

% nPop=100;% 人口规模（家庭规模）
%%%%%%%%%%%%%%%%%%%%%%初始人数设定%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nBabysitter= 3;% 保姆人数
nAlphaGroup=nPop-nBabysitter;% Alpha组数
nScout=nAlphaGroup;% 侦察人数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

peep=2;%阿尔法女声
% 空猫鼬结构
empty_mongoose.Position=[];
empty_mongoose.Cost=[];

% 初始化人口数组
pop=repmat(empty_mongoose,nAlphaGroup,1);

%初始化有史以来最好的解决方案
BestSol.Cost=inf;
tau=inf;
Iter=1;
sm=inf(nAlphaGroup,1);

% 创建初始种群
for i=1:nAlphaGroup
    pop(i).Position=unifrnd(VarMin,VarMax,VarSize);
    pop(i).Cost=fobj(pop(i).Position);
    if pop(i).Cost<=BestSol.Cost
        BestSol=pop(i);
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%   Cricle混沌映射  %%%%%%%%%%%%%%%%%%%%%%%%%%%%
% a=0.5;
% b=0.2;
% for i =1:nAlphaGroup
%     INpop(i).Position=unifrnd(VarMin,VarMax,VarSize);
%     pop(i).Position=mod((INpop(i).Position)+b-(a/2/pi)*sin(2.*pi.*INpop(i).Position),1);
%     pop(i).Cost=F_obj(pop(i).Position);
%     if pop(i).Cost<=BestSol.Cost
%         BestSol=pop(i);
%     end
% end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%  Fuch映射  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% for i = 1:nAlphaGroup
%    INpop(i).Position=unifrnd(VarMin,VarMax,VarSize);
%    Spop(i).Position=cos(1./(INpop(i).Position).^2);
%    Tpop(i).Position=LB+Spop(i).Position*(UB-LB);
%    m=rand();
%    OXpop(i).Position=m*(min(Tpop(i).Position)-max(Tpop(i).Position))-Tpop(i).Position;
%    pop(i).Position=OXpop(i).Position;
%    pop(i).Cost=F_obj(pop(i).Position);
%     if pop(i).Cost<=BestSol.Cost
%         BestSol=pop(i);
%     end
% end
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 遗弃柜台
C=zeros(nAlphaGroup,1);
% 保存最优值的数组
BestCost2=zeros(MaxIt,1);
L=round(0.6*nVar*nBabysitter);

%% DMOA 主循环

for Iter=1:MaxIt

 %%%%%%%%%%%%%%%%%%%%%%加入非线性权重因子%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % w=wmin+(wmax-wmin)*(1-sin((Iter*pi)/(MaxIt*2)));
    % w=((wmax+wmin)/2)*(1-sin((pi*Iter)/(MaxIt*2)));
        % r=rand();
        % w=wmin+(wmax-wmin)*r*(1-sin((Iter*pi)/(MaxIt*2)));
    % Iter=Iter+1;
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 阿尔法组
     F=zeros(nAlphaGroup,1);
     MeanCost = mean([pop.Cost]);

%%%%%%%%%%%%%%%%%%%%%%   加入ROL反向学习  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %  for i=1:nAlphaGroup
    %     s1=rand();%%%%%%%%%%原公式中加入rand
    %     s2=rand();
    %     UB=VarMax;
    %     LB=VarMin;
    %     % UB=max(pop(i).Position);
    %     % LB=min(pop(i).Position);
    %     X=pop(i).Position;
    %     % ROLpop(i).Position=UB+LB-s.*X;
    %     ROLpop(i).Position=X+s1*(s2*(UB+LB-X)-X);
    %     pop(i).Cost=F_obj(pop(i).Position);
    %     ROLpop(i).Cost=F_obj(ROLpop(i).Position);
    %     if ROLpop(i).Cost<pop(i).Cost
    %         pop(i).Cost=ROLpop(i).Cost;
    %         pop(i).Position=ROLpop(i).Position;
    %     end
    %     if pop(i).Cost<=BestSol.Cost
    %     BestSol=pop(i);
    %     end
    % end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%  Plwcm混沌映射反向学习 %%%%%%%%%%%%%%%%%%%%%%%%%%%

for i=1:nAlphaGroup
    p=0.2;
    X=pop(i).Position;
    if (0<=X) & (X<p)
        pop(i).Position=(X)/p;
    end
    if p<=X & X<0.5
        pop(i).Position=(X-p)/0.5;
    end
    if 0.5<=X & X<1-p
        pop(i).Position=(1-p-X)/(0.5-p);
    end
    if 1-p<=X & X<=1
        pop(i).Position=(1-X)/p;
    end
    UB=VarMax;
    LB=VarMin;
    P=pop(i).Position;
    r=rand();
    OBLpop(i).Position=UB+LB-r*P;
    pop(i).Cost=fobj(pop(i).Position);
    OBLpop(i).Cost=fobj(OBLpop(i).Position);
    if OBLpop(i).Cost<pop(i).Cost
        pop(i).Cost=OBLpop(i).Cost;
        pop(i).Position=OBLpop(i).Position;
   end
    if pop(i).Cost<=BestSol.Cost
        BestSol=pop(i);
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    for i=1:nAlphaGroup
        
        % 计算适应度值和 Alpha 的选择
        F(i) = exp(-pop(i).Cost/MeanCost); %%%%%%%%%%%%%适应度
    end
        P=F/sum(F);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%雌性首领产生

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%黄金正余弦参数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % t=0.618;
    % e=2.71;
    % r1=rand();
    % r2=2*(1-(Iter/MaxIt));
    % r3=rand();
    % r4=randperm(50,1);
    % m1=-2*pi+(1-t)*2*pi;
    % m2=-2*pi+t*2*pi;
    % C1=2*e^(-((4*r4*Iter)/MaxIt)^2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

      %由 Alpha 女性领导的觅食
    for m=1:nAlphaGroup
        % 
        i=RouletteWheelSelection(P);%%%%%%%%%%%轮盘随机产生领导
        % % 随机选择k，不等于Alpha
        K=[1:i-1 i+1:nAlphaGroup];%%%%%%%%%%%%%Alpha组其他成员
        k=K(randi([1 numel(K)]));
        % 定义发声系数。
        phi=(peep/2)*unifrnd(-1,+1,VarSize);
       %新猫鼬位置
 %%%%%%%%%%%%%%%%%%%%%%%%%%% 加入黄金正弦算法 %%%%%%%%%%%%%%%%%%%%%%%%%%%%
         % rand_num = rand(); % 生成0到1之间的随机数
         % R1=rand_num*2*pi;%生成0到2pi随机数
         % R2= rand_num * pi; % 将随机数乘以pi得到0到pi之间的随机数
         % t=(sqrt(5)-1)/2;
         % a=-pi*(1-t)+pi*t;
         % b=-pi*t+pi*(1-t);
         %  % newpops.Position=(1-w)*pop(k).Position*abs(sin(R1))+w*R2*sin(R1)*abs(a*pop(i).Position-b*pop(k).Position);
         %  newpops.Position=(1-w).*pop(k).Position.*abs(sin(R1))-w.*phi.*R2.*sin(R1).*(a.*pop(i).Position-b.*pop(k).Position);%%%食物源新位置
%%%%%%%%%%%%%%%%%%%%%%%%%%  加入黄金正余弦算法  %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%  加入非线性权重因子  %%%%%%%%%%%%%%%%%%%%%%%%%%%
       % r=rand();
       % if r<0.5
       %     newpops.Position=(1-w)*pop(k).Position*abs(sin(r1))*C1+w*r2*sin(r3)*abs(m1*pop(i).Position-m2*pop(k).Position);
       % else
       %     newpops.Position=(1-w)*pop(k).Position*abs(cos(r1))*C1+w*r2*cos(r3)*abs(m1*pop(i).Position-m2*pop(k).Position);
       % end
% %%%%%%%%%%%%%%%%%%%%%%%%% 贪心机制  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
       newpop.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);%%%食物源新位置
       % fitness1=F_obj(newpops.Position);
       % fitness2=F_obj(newpop.Position);
       % if fitness1<fitness2
       %     newpop.Position=newpops.Position;
       % else
       %     newpop.Position=newpop.Position;
       % end
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%  贪心机制 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %     newpop.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);%%%食物源新位置     
    %     newpops(i).Cost=F_obj(newpops(i).Position);
    %     newpop(i).Cost=F_obj(newpop(i).Position);
    %     if newpops(i).Cost<newpop(i).Cost
    %         newpop.Cost=newpops(i).Cost;
    %         newpop.Position=newpops(i).Position;
    %     end
    %     if pop(i).Cost<=BestSol.Cost
    %     BestSol=pop(i);
    %     end
    % end

% %%%%%%%%%%%%%%%%%%%%%%%   ROL  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 反向学习，重要一环  
%         s=rand();%%%%%%%%%%原公式中加入rand
%         UB=VarMax;
%         LB=VarMin;
%         X=newpop.Position;
%         newpop.Position=UB+LB-s.*X;
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%  反向限制学习 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % s=rand();%%%%%%%%%%原公式中加入rand
        % UB=max(newpop.Position);
        % LB=min(newpop.Position);
        % X=newpop.Position;
        % newpop.Position=s*(UB+LB-X);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        %评估
        newpop.Cost=fobj(newpop.Position);
        % 比较
        if newpop.Cost<=pop(i).Cost
            pop(i)=newpop;
        else
            C(i)=C(i)+1;
        end
   end   
        %侦察组
    for i=1:nScout
        % 随机选择k，不等于i
        K=[1:i-1 i+1:nAlphaGroup];
        k=K(randi([1 numel(K)]));
        % 定义发声系数。
        phi=(peep/2)*unifrnd(-1,+1,VarSize);
 %%%%%%%%%%%%%%%%%%%%%%%%%%% 加入黄金正弦算法 %%%%%%%%%%%%%%%%%%%%%%%%%%%%
         % rand_num = rand(); % 生成0到1之间的随机数
         % R1=rand_num*2*pi;%生成0到2pi随机数
         % R2= rand_num * pi; % 将随机数乘以pi得到0到pi之间的随机数
         % t=(sqrt(5)-1)/2;
         % a=-pi*(1-t)+pi*t;
         % b=-pi*t+pi*(1-t);
         % % newpop1.Position=(1-w)*pop(k).Position*abs(sin(R1))+w*R2*sin(R1)*abs(a*pop(i).Position-b*pop(k).Position);
         % newpop1.Position=(1-w).*pop(k).Position.*abs(sin(R1))+w.*phi.*R2.*sin(R1).*(a.*pop(i).Position-b.*pop(k).Position);%%%食物源新位置

% %%%%%%%%%%%%%%%%%%%%%%%%%%  加入黄金正余弦算法  %%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%  加入非线性权重因子  %%%%%%%%%%%%%%%%%%%%%%%%%%%
       % r=rand();
       % if r<0.5
       %     newpop1.Position=(1-w)*pop(k).Position*abs(sin(r1))*C1+w*r2*sin(r3)*abs(m1*pop(i).Position-m2*pop(k).Position);
       % else
       %     newpop1.Position=(1-w)*pop(k).Position*abs(cos(r1))*C1+w*r2*cos(r3)*abs(m1*pop(i).Position-m2*pop(k).Position);
       % end
% %%%%%%%%%%%%%%%%%%%%%%%%% 贪心机制  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
       newpop.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);%%%食物源新位置
       % fitness1=F_obj(newpop1.Position);
       % fitness2=F_obj(newpop2.Position);
       % if fitness1<fitness2
       %     newpop.Position=newpop1.Position;
       % else
       %     newpop.Position=newpop2.Position;
       % end
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        % 新猫鼬位置
        % newpop.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);
        %评估
        newpop.Cost=fobj(newpop.Position);
        % 睡模
        sm(i)=(newpop.Cost-pop(i).Cost)/max(newpop.Cost,pop(i).Cost);%%%睡眠丘值。
        %比较
        if newpop.Cost<=pop(i).Cost
            pop(i)=newpop;
        else
            C(i)=C(i)+1;
        end
    end  

    % 保姆
%%%%%%%%%%%%%%%%%%%%%%%  保姆交换参数加入非线性因子 %%%%%%%%%%%%%%%%%%%%%%%%
    % T=MaxIt;
    % k=2;
    % e=2.7182;
    % Alpha=0.4-0.2*[(e^(Iter/T)-1)/(e-1)]^k;
    % % r=rand();
    % % R=r*(pi/2);
    % % e=2.7182;
    % % k=3;
    % % Alpha=0.6-e^(tan((pi*Iter)/2*MaxIt))^k;
    % L1=round(0.6*nVar*nBabysitter); % 保姆交换参数
    % % L=round(Alpha*nVar*nBabysitter);
    % L=Alpha*L1;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    for i=1:nBabysitter
        if C(i)>=L
            pop(i).Position=unifrnd(VarMin,VarMax,VarSize);%%%%%交换过后结果
            pop(i).Cost=fobj(pop(i).Position);
            C(i)=0;
        end
    end    
     % 更新找到的最佳解决方案
    for i=1:nAlphaGroup
        if pop(i).Cost<=BestSol.Cost
            BestSol=pop(i);
        end
    end    
  % 下一个猫鼬位置，新种群位置
   newtau=mean(sm);
   CF=(1-Iter/MaxIt)^(2*Iter/MaxIt);
   % r1=rand();
   % r2=rand();
%%%%%%%%%%%%%%%%%%%%%%%%%%% 非线性时变自适应权重wf %%%%%%%%%%%%%%%%%%%%%%%%%
   % for i=1:MaxIt
   %     if Iter<=(MaxIt/2)
   %         wf=((1+cos((pi*Iter)/MaxIt))^(1/k))/2;
   %     else
   %         wf=((1-cos(pi+(pi*Iter)/MaxIt))^(1/k))/2;
   %     end
   % end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   for i=1:nScout
     M=(pop(i).Position.*sm(i))/pop(i).Position;

        % if newtau>tau%%%%%%寻找新睡眠
        %      newpop.Position=pop(i).Position-CF*phi*rand.*(pop(i).Position-M);
        % else
        %    newpop.Position=pop(i).Position+CF*phi*rand.*(pop(i).Position-M);
        % end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  wf加入 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        if newtau>tau%%%%%%寻找新睡眠
             newpop.Position=pop(i).Position-CF*phi*rand.*(pop(i).Position-M);
        else
           newpop.Position=pop(i).Position+CF*phi*rand.*(pop(i).Position-M);
        end
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        tau=newtau;
   end
       
   % 更新找到的最佳解决方案
    for i=1:nAlphaGroup
        if pop(i).Cost<=BestSol.Cost
            BestSol=pop(i);
        end
    end
    
    %存储有史以来最好的成本
    BestCost2(Iter)=BestSol.Cost;
    BEF2=BestSol.Cost;
    BEP2=BestSol.Position;
    % 显示迭代信息
    disp(['Iteration ' num2str(Iter) ': Best Cost = ' num2str(BestCost2(Iter))]);
    

end

